#include "HttpServer.hpp"
#include "Err.hpp"
#include "Util.hpp"
#include <vector>
#include <unordered_map>
#include <utility>
#include <memory>

const std::string SEP = "\r\n";
const std::string defaultHomepage = "test.html";
const std::string webroot = "./wwwroot"; // 根目录
const std::string page_404 = "./wwwroot/err_404.html";

class HttpRequest
{
public:
    HttpRequest() : _path(webroot)
    {
    }

    ~HttpRequest()
    {
    }

    void Print()
    {
        logmessage(INFO, "method: %s,url: %s,version: %s",
                   _method.c_str(), _url.c_str(), _httpVersion.c_str());
        // for (auto &it : _body)
        // {
        //     logmessage(DEBUG, "-%s", it.c_str());
        // }

        logmessage(DEBUG, "path: %s", _path.c_str());
    }

    std::string _method;
    std::string _url;
    std::string _httpVersion;
    std::vector<std::string> _body;
    std::string _path;
    std::string _suffix;
};

HttpRequest Deserialize(std::string &message)
{
    HttpRequest req;
    std::string line = Util::ReadOneLine(message, SEP);
    Util::ParseRequestLine(line, &req._method, &req._url, &req._httpVersion);

    while (!message.empty())
    {
        line = Util::ReadOneLine(message, SEP);
        req._body.push_back(line);
    }

    req._path += req._url;
    if (req._path[req._path.size() - 1] == '/')
        req._path += defaultHomepage;

    auto pos = req._path.find(".");
    if (pos == std::string::npos)
        req._suffix = ".html";
    req._suffix = req._path.substr(pos);
    return req;
}

std::string GetContentType(const std::string &suffix)
{
    std::string content_type = "Content-Type: ";
    if (suffix == ".html" || suffix == ".htm")
        content_type += "text.html";
    else if (suffix == ".css")
        content_type += "text/css";
    else if (suffix == ".js")
        content_type += "application/x-javascript";
    else if (suffix == ".png")
        content_type += "image/png";
    else if (suffix == ".jpg")
        content_type += "image/jpeg";
    else
    {
    }
    return content_type + SEP;
}

struct Session
{
    std::string _name;
    std::string _password;
    uint64_t loginTime;
    int status;
    int fd;
    int sesisonid;
};

std::unordered_map<int, Session *> sessions;

// bool Login(std::string &message)
// {
//     std::string name, passwd;
//     if (check(name, passwd))
//     {
//         Session *newsession = new Session(name, passwd);
//         int random = rand();
//         sessions.insert(make_pair(random, newsession));
//     }

//     http response;
// }

std::string HeaderHttp(std::string &request)
{
    // 读取请求
    std::cout << "------------------------------------" << std::endl;
    std::cout << request << std::endl;

    // 反序列化和分析请求
    HttpRequest req = Deserialize(request);
    req.Print();

    // 使用请求
    std::string body;
    std::string response;
    if (true == Util::Readfile(req._path, &body))
    {
        response = "HTTP/1.0 200 OK" + SEP;
        response += "Content-Length: " + std::to_string(body.size()) + SEP;
        response += GetContentType(req._suffix);
        response += SEP;
        response += body;
    }
    else
    {
        response = "HTTP/1.0 404 Not Found" + SEP;
        Util::Readfile(page_404, &body);
        response += "Content-Length: " + std::to_string(body.size()) + SEP;
        response += GetContentType(".html");
        response += SEP;
        response += body;
    }

    // 重定向
    // std::string response;
    // response = "HTTP/1.0 301 Move Permanently" + SEP;
    // response += ("Location: https://www.baidu.com/" + SEP);
    // response += SEP;

    // 登陆界面时检测对应的sesion信息
    // 状态正常则返回对应应答

    return response;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        exit(USAGE_ERR);
    }
    uint16_t port = atoi(argv[1]);
    std::unique_ptr<HttpServer> stvr(new HttpServer(HeaderHttp, port));
    stvr->InitServer();
    stvr->Start();
    return 0;
}
